package com.mock.water.config.shiro;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mock.water.core.utils.JwtUtils;
import com.mock.water.modules.system.user.entity.UserEntity;
import com.mock.water.modules.system.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;

/**
 * @Author ifredomvip@gmail.com
 * @Date 2023/3/26 0:56
 */
@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 授权
     *
     * @param principalCollection 主要收集
     * @return {@link AuthorizationInfo}
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println("调用授权验证" + primaryPrincipal);

        if ("admin".equals(primaryPrincipal)) {
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            authorizationInfo.addRole("admin");
            return authorizationInfo;
        }
        return null;
    }

    /**
     * 身份验证信息
     *
     * @param authenticationToken 身份验证令牌
     * @return {@link AuthenticationInfo}
     * @throws AuthenticationException 身份验证异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("进入 UserRealm身份验证");

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        String username = token.getUsername();

        if (username == null) {
            throw new AuthenticationException("token invalid");
        }

        // 查询用户
        UserEntity user = Optional.ofNullable(userService.getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUsername, username)))
                .orElseThrow(() -> new UnknownAccountException("用户名或密码不正确"));

        if (user.getStatus() == null || user.getStatus().equals(1)) {
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }

        SecurityUtils.getSubject().getSession().setAttribute("User", user);

        // getName()是获取 UserRealm的名字
        return new SimpleAuthenticationInfo(
                user,
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                getName()
        );
    }

}
